package org.game.module.datingbo.handler;

import com.sojoys.artifact.constant.ArtifactErrorCode;
import com.sojoys.artifact.tools.ToolError;
import org.cfg.DatingCfg;
import org.cfg.DatingRuleCfg;
import org.constant.DatingConstant;
import org.error.GameErrorCode;
import org.game.constant.DatingTypeConstant;
import org.game.db.bean.*;
import org.game.db.cache.CityDatingRecordCache;
import org.game.db.cache.RoleCache;
import org.game.log.LogDating;
import org.game.log.builder.LogDsp;
import org.game.log.dsp.DatingDsp;
import org.game.log.dsp.GoodsDsp;
import org.game.manager.RoleManager;
import org.game.module.datingbo.DatingBO;
import org.game.module.datingbo.DatingType;
import org.game.msgBuilder.DatingMsgBuilder;
import org.game.protobuf.c2s.C2SDatingMsg;
import org.game.protobuf.s2c.S2CShareMsg;

import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Created by fxf on 2017/11/20.
 */
@DatingType(DatingTypeConstant.DATING_TYPE_RESERVE)
public class ReserveDatingHandler extends AbstractDatingHandler {

    @Override
    public byte[] getScript(Player player, C2SDatingMsg.GetScriptMsg msg) {
        long cityDatingRecordId = Long.valueOf(msg.getCityDatingId());
        CityDatingRecord record = CityDatingRecordCache.me().getById(cityDatingRecordId);

        ToolError.isAndTrue(ArtifactErrorCode.PARAM_ERROR, "获取预约约会剧本，记录id错误", record == null);
        ToolError.isAndTrue(GameErrorCode.DATING_IS_NO_ACCEPT_STATE, "非接受邀请状态，不能进行约会",
                record.getCityDatingRecordProxy().getState() == DatingConstant.RESERVE_DATING_STATE_NO_DATING
                        || record.getCityDatingRecordProxy().getState() == DatingConstant.RESERVE_DATING_STATE_HAVE_INVITATION );
        ToolError.isAndTrue(GameErrorCode.IS_NOT_DATING_TIME_YET,"预定约会时间未到",System.currentTimeMillis() < record.getCityDatingRecordProxy().getDatingBeginTime());

        DatingRuleCfg datingRuleCfg = record.getCityDatingRecordProxy().getCfg();

        //判断时间
        int timeState = getReverseDatingTimeState(record);

        int scriptId = datingRuleCfg.getId();
        int startNodeId = getStartNodeId(scriptId);
        if (timeState == DatingConstant.RESERVE_DATING_TIME_STATE_LATE_IN_DAY) {
            //约会迟到处理：
            //1.迟到惩罚
            //2.发送失败剧本id
            //3.删除城市约会记录，并发送到客户端
            //4.更新城市状态为非约会占用状态
            scriptId = (int) datingRuleCfg.getOtherScriptIds().get(DatingConstant.FAIL_SCRIPT_ID);
            Role role = RoleCache.me().getByCidPlayerId(record.getCityDatingRecordProxy().getRoleCids().get(0),player.getId());

            LogDsp logDsp = LogDsp.newBuilder(GoodsDsp.RESERVE_FAIL);
            Optional<Map> optMap = Optional.ofNullable((Map) datingRuleCfg.getOtherInfo().get(DatingConstant.FAIL_REWARD));
            Optional<Integer> optFavor = optMap.map(map->(Integer) map.get(DatingConstant.ANSWER_FAVOR));
            if (optFavor.isPresent()){
                RoleManager.me().changeFavor(role,optFavor.get(),logDsp);
            }
            Optional<Integer> optMood = optMap.map(map->(Integer) map.get(DatingConstant.ANSWER_MOOD));
            if (optMood.isPresent()){
                RoleManager.me().changeMood(role,optMood.get(),logDsp);
            }
            player.getPlayerProxy().sendMsg(DatingBO.sendEveryDayScript,DatingMsgBuilder.getDatingScriptMsg(scriptId,null));
            record.delete();
            player.getPlayerProxy().sendMsg(DatingBO.sendCityDating,DatingMsgBuilder.getCityDatingInfo(S2CShareMsg.ChangeType.DELETE,record));
            updateCity(player, record.getCityDatingRecordProxy().getCfg());
        }else{
            Map<Integer, List<Integer>> branchNodes = getScriptBranchNode(player, scriptId,msg);
            createCurrentScriptRecord(player, scriptId, branchNodes, startNodeId, record.getCityDatingRecordProxy().getRoleCids());
            LogDating.me().log(player.getId(),DatingTypeConstant.DATING_TYPE_RESERVE,scriptId,player.getPlayerProxy().getCurrentRole().getRoleProxy().getConfig().getId(), LogDsp.newBuilder(DatingDsp.GET_SCRIPT));
            player.getPlayerProxy().sendMsg(DatingBO.sendEveryDayScript,DatingMsgBuilder.getDatingScriptMsg(record.getCid(),branchNodes));
        }
        return new byte[0];
    }

    /**
     * 获取预约约会的时间状态
     *
     * @return 0：正常约会时间 1：迟到，但未跨天 2：迟到且跨天
     */
    private int getReverseDatingTimeState(CityDatingRecord record) {
        Calendar beginTime = Calendar.getInstance();
        beginTime.setTimeInMillis(record.getCityDatingRecordProxy().getDatingBeginTime());

        Calendar endTime = Calendar.getInstance();
        endTime.setTimeInMillis(record.getCityDatingRecordProxy().getDatingEndTime());

        Calendar now = Calendar.getInstance();

        if (beginTime.getTimeInMillis() <= now.getTimeInMillis() && endTime.getTimeInMillis() >= now.getTimeInMillis()) {
            return DatingConstant.RESERVE_DATING_TIME_STATE_ON_TIME;
        } else {
            return DatingConstant.RESERVE_DATING_TIME_STATE_LATE_IN_DAY;
        }
    }

    @Override
    protected void endDatingRecord(Player player, Dating dating, DatingCfg cfg,int roleCid,CurrentScriptRecord record) {
        super.endDatingRecord(player,dating,cfg,roleCid,record);

        CityDatingRecord cityDatingRecord = CityDatingRecordCache.me().getCityDatingRecordCacheProxy().getByPlayerIdDatingTypeRoleCid(player.getId(),getDatingType(),roleCid);
        //城市约会记录有可能在约会完成之前就被定时器删除掉，删除以后不会影响当前约会
        if (cityDatingRecord != null){
            cityDatingRecord.delete();
            player.getPlayerProxy().sendMsg(DatingBO.sendCityDating,DatingMsgBuilder.getCityDatingInfo(S2CShareMsg.ChangeType.DELETE,cityDatingRecord));
            updateCity(player, cityDatingRecord.getCityDatingRecordProxy().getCfg());
        }
    }

    /**
     * 回应邀请
     */
    public void answerInvitation(Player player, CityDatingRecord record, boolean accept) {
        if (accept) {
            record.getCityDatingRecordProxy().setState(DatingConstant.RESERVE_DATING_STATE_ACCEPT_INVITATION);
            record.update();
        } else {
            record.getCityDatingRecordProxy().setState(DatingConstant.RESERVE_DATING_STATE_NO_DATING);
            record.delete();
            updateCity(player,record.getCityDatingRecordProxy().getCfg());
        }

    }
}
